package com.cf.game.cowboy;

import com.cf.game.cowboy.handler.model.GameResult;
import com.cf.game.cowboy.handler.model.StakeGroup;
import com.cf.game.cowboy.handler.model.StakeItem;
import com.cf.game.cowboy.handler.model.UserStake;
import com.cf.game.cowboy.msg.CowGameInfoResponse;
import com.cf.game.cowboy.vo.StakeGroupVo;
import com.cf.game.cowboy.vo.StakeVo;
import com.cf.game.service.constants.EnumReturnCode;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * cf-game-GameStateDetail
 *
 * @author <a href="2428922347@qq.com">Zhu mingming</a>
 * @info
 * @since 2018/3/27 16:26
 */
public class GameStateDetail {

    private GameResult gameResult;

    public static final String winGroup = "win-group";

    public static final String bulletGroup = "bullet-group";

    private Map<String, List<StakeItem>> userStakes = new ConcurrentHashMap();

    private static final Map<String, StakeGroup> group = new HashMap();

    private Long start = System.currentTimeMillis();


    public GameStateDetail() {
        refresh();
    }

    static {
        initStakeGroupInfo();
    }


    public void refresh() {
        start = System.currentTimeMillis();
        refreshUserStakeMap();
    }


    public Long getLeftTime() {
        long leftTime = (CowBoyGame.Stake_Time / 1000) - ((System.currentTimeMillis() - start) / 1000);
        return leftTime >= 0 ? leftTime : 0;
    }

    private static void initStakeGroupInfo() {
        group.put(winGroup, createWinGroup());
        group.put(bulletGroup, createBulletGroup());
    }

    private void refreshUserStakeMap() {
        Map<String, List<StakeItem>> map = new ConcurrentHashMap();
        addWinStakeGroup(map);
        addGunGroup(map);
        userStakes = map;
    }

    private void addWinStakeGroup(Map<String, List<StakeItem>> map) {
        List<StakeItem> items = new CopyOnWriteArrayList();

        StakeItem jkStakeItem = new StakeItem();
        jkStakeItem.setId("jk-win");
        jkStakeItem.setBei(1.8);
        jkStakeItem.setName("杰克赢");
        items.add(jkStakeItem);

        StakeItem yhStakeItem = new StakeItem();
        yhStakeItem.setId("yh-win");
        yhStakeItem.setBei(1.8);
        yhStakeItem.setName("约翰赢");
        items.add(yhStakeItem);

        map.put(winGroup, items);
    }


    private void addGunGroup(Map<String, List<StakeItem>> map) {
        List<StakeItem> items = new CopyOnWriteArrayList();

        StakeItem firstStakeItem = new StakeItem();
        firstStakeItem.setId("1-win");
        firstStakeItem.setBei(5);
        firstStakeItem.setName("第一枪");
        items.add(firstStakeItem);

        StakeItem secondStakeItem = new StakeItem();
        secondStakeItem.setId("2-win");
        secondStakeItem.setBei(5);
        secondStakeItem.setName("第二枪");
        items.add(secondStakeItem);

        StakeItem thirdStakeItem = new StakeItem();
        thirdStakeItem.setId("3-win");
        thirdStakeItem.setBei(5);
        thirdStakeItem.setName("第三枪");
        items.add(thirdStakeItem);

        StakeItem fourthStakeItem = new StakeItem();
        fourthStakeItem.setId("4-win");
        fourthStakeItem.setBei(5);
        fourthStakeItem.setName("第四枪");
        items.add(fourthStakeItem);

        StakeItem fifthStakeItem = new StakeItem();
        fifthStakeItem.setId("5-win");
        fifthStakeItem.setName("第五枪");
        fifthStakeItem.setBei(5);
        items.add(fifthStakeItem);

        StakeItem SixthStakeItem = new StakeItem();
        SixthStakeItem.setId("6-win");
        SixthStakeItem.setBei(5);
        SixthStakeItem.setName("第六枪");
        items.add(SixthStakeItem);

        map.put(bulletGroup, items);
    }

    private static StakeGroup createBulletGroup() {
        StakeGroup stakeGroup = new StakeGroup();
        stakeGroup.setId("bullet-group");
        stakeGroup.setName("猜子弹");
        return stakeGroup;
    }

    private static StakeGroup createWinGroup() {
        StakeGroup stakeGroup = new StakeGroup();
        stakeGroup.setId("win-group");
        stakeGroup.setName("猜谁赢");
        return stakeGroup;
    }

    public void userAddStake(Integer userId, String groupId, String stakeId, double money) {
        List<StakeItem> items = userStakes.get(groupId);
        StakeItem stakeItem = getTargetStakeItem(items, stakeId);
        stakeItem.addUserStake(userId, money);
    }

    private StakeItem getTargetStakeItem(List<StakeItem> items, String stakeId) {
        for (StakeItem item : items) {
            if (stakeId.equals(item.getId())) {
                return item;
            }
        }
        return null;
    }


    public CowGameInfoResponse toCowQueryGameInfoResponse(Integer userId) {
        List<StakeGroupVo> stakeGroups = new ArrayList();

        Set<Map.Entry<String, List<StakeItem>>> entries = userStakes.entrySet();

        entries.forEach(stringListEntry -> {
            StakeGroup stakeGroup = group.get(stringListEntry.getKey());
            StakeGroupVo stakeGroupVo = new StakeGroupVo();
            stakeGroups.add(stakeGroupVo);
            BeanUtils.copyProperties(stakeGroup, stakeGroupVo);
            List<StakeItem> value = stringListEntry.getValue();

            List<StakeVo> stakeVos = new ArrayList<>();
            value.forEach(stakeItem -> {
                StakeVo stakeVo = new StakeVo();
                BeanUtils.copyProperties(stakeItem, stakeVo);
                Double selfTotal = getSelf(stakeItem, userId);
                stakeVo.setSelfMoney(selfTotal);
                stakeVos.add(stakeVo);
            });
            stakeGroupVo.setStakes(stakeVos);
        });

        CowGameInfoResponse cowGameInfoResponse = new CowGameInfoResponse("获取游戏状态成功！", EnumReturnCode.SUCCESS.getCode(), stakeGroups, this.getLeftTime());
        if (this.gameResult != null)
            cowGameInfoResponse.setWinIndex(this.gameResult.getWinIndex());
        return cowGameInfoResponse;
    }

    private Double getSelf(StakeItem stakeItem, Integer userId) {
        Map<Integer, UserStake> stakeMap = stakeItem.getStakeMap();
        UserStake userStake = stakeMap.get(userId);
        if (userStake == null)
            return 0d;
        else
            return userStake.getTotal();
    }

    public GameResult getGameResult() {
        return gameResult;
    }

    public void setGameResult(GameResult gameResult) {
        this.gameResult = gameResult;
    }

    public Map<String, List<StakeItem>> getUserStakes() {
        return userStakes;
    }

    public void setUserStakes(Map<String, List<StakeItem>> userStakes) {
        this.userStakes = userStakes;
    }
}
